﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Extensil.Common;
using Vibz.TeamAssignment.Common.Entity;
using Vibz.TeamAssignment.Common;

namespace Vibz.TeamAssignment
{
    public partial class ViewAssignment :BaseCategory
    {
        bool _isFirstTimeLoad = true;
        BackgroundWorker bwLoader;
        AssignmentClient _aClient;
        TaskGrid tGrid;
        string _errorText = "";
        public string ErrorText
        {
            get
            {
                return _errorText;
            }
            set
            {
                _errorText = value;
                tsbError.Visible = !String.IsNullOrEmpty(_errorText);
            }
        }
        public ViewAssignment()
        {
            InitializeComponent();
            toolStrip1.Padding = new Padding(0, 0, 0, 0);
            splitContainer1.Panel2Collapsed = true;
            LoadManager();
        }
        void Reload()
        {
            LoadManager();
            LoadControls(); 
        }
        void LoadManager()
        {
            try
            {
                _aClient = new AssignmentClient(ReportProgress);
            }
            catch(ManagerNotDefinedException exc)
            {
                ErrorText = "You must configure assignment manager to run this application.";
                ReportProgress(100, "You must configure assignment manager to run this application.");
            }
            catch(Exception exc)
            {
                ErrorText = "Error occured while loading your assignments. " + exc.Message;
                ReportProgress(100, "Error occured while loading your assignments. " + exc.Message);
            }
        }
        void tGrid_TaskLoadRequired(object sender, TaskLoadEventArgs e)
        {
            LoadTaskInfo(e.Operation, e.TaskID);
        }

        void tGrid_CellClick(object sender, TaskGridEventArgs e)
        {
            LoadTaskInfo(TaskOperation.Edit, e.Task.TaskID);
        }

        protected override void OnLoad(EventArgs e)
        {
            LoadControls();
        }
        void LoadControls()
        {
            if(_aClient == null)
                return;

            try
            {
                _aClient.Connect();
            }
            catch(ParameterNotDefinedException exc)
            {
                ErrorText = "Configuration incomplete. " + exc.Parameter + " is not defined.";
                ReportProgress(100, "Configuration incomplete. " + exc.Parameter + " is not defined.");
                return;
            }
            catch(Exception exc)
            {
                ErrorText = "Error occured while establishing connection with the assignments database. " + exc.Message;
                ReportProgress(100, "Error occured while establishing connection with the assignments database. " + exc.Message);
                return;
            }
            tGrid = new TaskGrid();
            tGrid.CellClick += new TaskGrid.TaskGridEventHandler(tGrid_CellClick);
            tGrid.TaskLoadRequired += new TaskGrid.TaskLoadEventHandler(tGrid_TaskLoadRequired);
            tGrid.ShowNewTaskMenu = true;
            tGrid.Dock = DockStyle.Fill;
            splitContainer1.Panel1.Controls.Add(tGrid);
            splitContainer1.Panel1.AutoScroll = true;
            splitContainer1.Panel2.AutoScroll = true;
            splitContainer1.Panel1.VerticalScroll.Visible = true;
            splitContainer1.Panel2.VerticalScroll.Visible = true;
            tGrid.BringToFront();

            pbLoader.Visible = true;
            pbLoader.BringToFront();

            ErrorText = "";

            timerTaskQuery.Enabled = true;
            timerTaskQuery.Interval = _aClient.QueryInterval;
            timerTaskQuery.Start();

            reloadAllToolStripMenuItem.Visible = true;
            reConnectToolStripMenuItem.Visible = true;
            toolStripDropDownButton1.Visible = true;

            LoadReportee();
        }
        internal void LoadReportee()
        {
            RequestInit();

            bwLoader = new BackgroundWorker();
            bwLoader.WorkerReportsProgress = true;
            bwLoader.WorkerSupportsCancellation = true;
            bwLoader.DoWork += new DoWorkEventHandler(LoadReportee);
            bwLoader.ProgressChanged += new ProgressChangedEventHandler(bwLoader_ProgressChanged);
            bwLoader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwLoader_LoadReporteeCompleted);
            bwLoader.RunWorkerAsync();
        }

        internal void LoadTaskList()
        {
            RequestInit();

            bwLoader = new BackgroundWorker();
            bwLoader.WorkerReportsProgress = true;
            bwLoader.WorkerSupportsCancellation = true;
            bwLoader.DoWork += new DoWorkEventHandler(LoadTaskList);
            bwLoader.ProgressChanged += new ProgressChangedEventHandler(bwLoader_ProgressChanged);
            bwLoader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwLoader_LoadTaskListCompleted);
            bwLoader.RunWorkerAsync(userMenu.Text);
        }

        void bwLoader_LoadReporteeCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            RequestExit();
            if(_isFirstTimeLoad)
                LoadTaskList();
        }
        void bwLoader_LoadTaskListCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            RequestExit();
        }

        void bwLoader_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if(e.UserState.GetType() == typeof(KeyValuePair<string, object>))
            {

                KeyValuePair<string, object> op = (KeyValuePair<string, object>)e.UserState;
                switch(op.Key)
                {
                    case "cbReportee Fill":
                        if(op.Value != null)
                        {
                            List<string> users = (List<string>)op.Value;

                            if(users.Count > 0)
                            {
                                ToolStripMenuItemGrouped mi
                                    = new ToolStripMenuItemGrouped(
                                        "Self (" + AssignmentClient.CurrentUser + ")", 
                                        null, Users_SelectedIndexChanged);
                                mi.Tag = AssignmentClient.CurrentUser;
                                mi.Checked = true;
                                userMenu.DropDown.Items.Add(mi);
                                mi = new ToolStripMenuItemGrouped("Reportee");
                                userMenu.DropDown.Items.Add(mi);
                                foreach(string user in users)
                                {
                                    ToolStripMenuItemGrouped miUser
                                        = new ToolStripMenuItemGrouped(user, null, Users_SelectedIndexChanged);
                                    miUser.Tag = user;
                                    mi.DropDown.Items.Add(miUser);
                                }
                                userMenu.Visible = true;
                            }
                            else
                                userMenu.Visible = false;
        
                            userMenu.Text = AssignmentClient.CurrentUser;
                            //LoadTaskList();
                        }
                        break;
                    case "dgvTaskList Fill":
                        if(op.Value != null)
                        {
                            List<TaskView> taskList = (List<TaskView>)op.Value;
                            foreach(TaskView tv in taskList)
                            {
                                tv.Task.TaskDescription = _aClient.RevertRTF(tv.Task.TaskDescription);
                            }
                            Dictionary<TaskView, DeltaChange> delta = null;
                            if(tGrid.TaskList != null)
                            {
                                delta = TaskView.GetDeltaUpdate(tGrid.TaskList, taskList, AssignmentClient.CurrentUser);
                                if(delta != null && delta.Count > 0)
                                {
                                    FlashAlertForm frm = new FlashAlertForm(delta);
                                    frm.Owner = this;
                                    frm.StartPosition = FormStartPosition.Manual;
                                    frm.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width
                                        - frm.Width, Screen.PrimaryScreen.WorkingArea.Height - frm.Height);
                                    frm.Show();
                                }
                            }
                            tGrid.Load(taskList, delta, _aClient);
                        }
                        break;
                }
            }
            else
                ReportProgress(e.ProgressPercentage, e.UserState.ToString());
        }

        void LoadReportee(object sender, DoWorkEventArgs e)
        {
            try
            {
                bwLoader.ReportProgress(10, new KeyValuePair<string, object>("cbReportee Fill", 
                    _aClient.GetAsignee()));
            }
            catch(Exception exc)
            {
                timerTaskQuery.Stop();
                bwLoader.ReportProgress(100, "Error while loading reportees. " + exc.Message);
            }
        }

        void LoadTaskList(object sender, DoWorkEventArgs e)
        {
            try
            {
                Console.WriteLine(DateTime.Now.ToLongTimeString() + "\tLoadTaskList");
                timerTaskQuery.Stop();
                bwLoader.ReportProgress(20, new KeyValuePair<string, object>("dgvTaskList Fill",
                    _aClient.GetUsersTask(e.Argument.ToString(), ViewOption.Sequential)));
            }
            catch(Exception exc)
            {
                bwLoader.ReportProgress(100, "Error while loading task. " + exc.Message);
            }
        }

        void RequestInit()
        {
            toolStrip1.Padding = new Padding(50, 0, 0, 0);
            pbLoader.Visible = true;
        }

        void RequestExit()
        {
            toolStrip1.Padding = new Padding(0, 0, 0, 0);
            pbLoader.Visible = false;
        }

        void LoadTaskInfo(TaskOperation opr, int taskID)
        {
            Console.WriteLine(DateTime.Now.ToLongTimeString() + "\tLoading task informations. ID#" + taskID.ToString() + "(" + opr.ToString() + ")");
            if(opr == TaskOperation.EditInNew)
            {
                OpenAssignment(taskID);
                return;
            }

            CreateEditAssignment ceAss = null;
            if(splitContainer1.Panel2.Controls.Count != 0
                && splitContainer1.Panel2.Controls[0].GetType() == typeof(CreateEditAssignment))
            {
                ceAss = (CreateEditAssignment)splitContainer1.Panel2.Controls[0];
                if(ceAss.ContentChanged && AlertBox.ShowDialog("Content has been changed for previous task action. "
                    + "Do you like to save it before navigating to next task action?",
                    "Task not saved.", AlertBoxButtons.YesNo) == AlertResult.Yes)
                {
                    if(!ceAss.SaveTask())
                    {
                        tGrid.SelectRow(ceAss._ID);
                        return;
                    }
                }
                ceAss.LoadTaskInfo(opr, taskID);
            }
            else
            {
                ceAss = new CreateEditAssignment(opr, taskID);
                ceAss.TopLevel = false;
                ceAss.Dock = DockStyle.Fill;
                ceAss.FormBorderStyle = FormBorderStyle.None;
                ceAss.Show();
                ceAss.CreateUpdateComplete 
                    += new CreateEditAssignment.CreateUpdateCompleteEventHandler(ceAss_CreateUpdateComplete);

                splitContainer1.Panel2.Controls.Add(ceAss);
            }
            ceAss.Tag = taskID;
            splitContainer1.Panel2Collapsed = false;
        }

        void ceAss_CreateUpdateComplete(object sender, EventArgs e)
        {
            splitContainer1.Panel2Collapsed = true;
            LoadTaskList();
        }
        void OpenAssignment(int taskID)
        {
            CreateEditAssignment ceAss = new CreateEditAssignment(TaskOperation.Edit, taskID);
            ceAss.Tag = taskID;
            ceAss.Show();
        }
        void Users_SelectedIndexChanged(object sender, EventArgs e)
        {
            userMenu.Text = ((ToolStripMenuItemGrouped)sender).Tag == null
                ? AssignmentClient.CurrentUser
                : ((ToolStripMenuItemGrouped)sender).Tag.ToString();
            if(((ToolStripMenuItemGrouped)sender).Tag == null)
            {
                foreach(ToolStripItem item in ((ToolStripMenuItemGrouped)userMenu.DropDown.Items[1]).DropDown.Items)
                {
                    ToolStripMenuItemGrouped mi = (ToolStripMenuItemGrouped)item;
                    if(mi.Checked)
                    {
                        mi.Checked = false;
                        ((ToolStripMenuItem)mi.OwnerItem).Checked = false;
                        break;
                    }
                }
            }
            tGrid.Clear();
            LoadTaskList();
        }

        private void timerTaskQuery_Tick(object sender, EventArgs e)
        {
            LoadTaskList();
        }

        public override BaseSetting Setting
        {
            get
            {
                if(_aClient==null)
                    return new TaskSettings();

                return new TaskSettings(this, _aClient);
            }
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TaskSettings settings = null;
            if(_aClient == null)
                settings = new TaskSettings();
            else
                settings = new TaskSettings(this, _aClient);
            if(settings.ShowDialog() == DialogResult.OK)
            {
                _isFirstTimeLoad = true;
                this.Reload();
            }
        }

        private void adminSettingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AdminSettings settings = new AdminSettings();
            if(settings.ShowDialog() == DialogResult.OK)
            {
                _isFirstTimeLoad = true;
                this.Reload();
            }
        }

        private void reloadAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Console.WriteLine(DateTime.Now.ToLongTimeString() + "\tReload requested by user.");
            _aClient.ClearCache();
            LoadTaskList();
        }

        private void tsbError_Click(object sender, EventArgs e)
        {
            AlertBox.ShowDialog(ErrorText);
        }

        private void reConnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Reload();
        }

        private void importToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TaskImportExcel excel = new TaskImportExcel(_aClient);
            excel.ShowDialog();
        }
    }
}
